package game.targets.screen;

import game.targets.Constants;
import game.targets.Locator;
import game.targets.RayCallback;
import game.targets.input.InputHandler;
import game.targets.room.Room;

import com.badlogic.gdx.Gdx;
import com.badlogic.gdx.Screen;
import com.badlogic.gdx.graphics.Color;
import com.badlogic.gdx.graphics.GL20;
import com.badlogic.gdx.graphics.PerspectiveCamera;
import com.badlogic.gdx.graphics.g2d.BitmapFont;
import com.badlogic.gdx.graphics.g2d.SpriteBatch;
import com.badlogic.gdx.graphics.g3d.Environment;
import com.badlogic.gdx.graphics.g3d.ModelBatch;
import com.badlogic.gdx.graphics.g3d.attributes.ColorAttribute;
import com.badlogic.gdx.graphics.g3d.environment.DirectionalLight;
import com.badlogic.gdx.graphics.g3d.utils.CameraInputController;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer;
import com.badlogic.gdx.graphics.glutils.ShapeRenderer.ShapeType;

public class RoomScreen implements Screen, Constants {

	private PerspectiveCamera camera;
	private CameraInputController cameraController;
	private ModelBatch modelBatch;
	private Environment environment;
	private Room room;
	private ShapeRenderer chargeRenderer;
	private SpriteBatch uiBatch;
	private BitmapFont font, fontSmall, fontMedium, fontRed;
	private RayCallback rayCallback;
	private ShapeRenderer crosshair;
	private ScreenHandler screenHandler;
	private boolean pause;

	public RoomScreen(ScreenHandler screenHandler) {
		// create camera and environment
		modelBatch = new ModelBatch();
		environment = new Environment();
		environment.set(new ColorAttribute(ColorAttribute.AmbientLight, 0.4f, 0.4f, 0.4f, 1f));
		environment.add(new DirectionalLight().set(0.8f, 0.8f, 0.8f, -1f, -0.8f, -0.2f));
		camera = new PerspectiveCamera(75, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		camera.position.set(2f, 0f, 0.5f);
		camera.lookAt(-10, 0, 0);
		camera.near = 0.1f;
		camera.far = 300f;
		camera.update();
		crosshair = new ShapeRenderer();
		pause = false;

		// create objects specific to screen
		rayCallback = new RayCallback();
		room = new Room(this, camera, environment, rayCallback);
		chargeRenderer = new ShapeRenderer();
		chargeRenderer.setColor(new Color(1, 0, 0, 1));
		uiBatch = new SpriteBatch();
		font = new BitmapFont(Gdx.files.internal("data/white48.fnt"), false);
		fontRed=new BitmapFont(Gdx.files.internal("data/white.fnt"), false);
		fontSmall = new BitmapFont(Gdx.files.internal("data/white.fnt"), false);
		fontMedium = new BitmapFont(Gdx.files.internal("data/white40.fnt"), false);
		this.screenHandler = screenHandler;

		// set inputs
		cameraController = new CameraInputController(camera);
		InputHandler input = new InputHandler(room, cameraController, camera, rayCallback);
		// Gdx.input.setCursorCatched(true);
		Locator.getInputMultiplexer().addProcessor(input);
		// Locator.getInputMultiplexer().addProcessor(cameraController);
		Gdx.input.setInputProcessor(Locator.getInputMultiplexer());
	}

	@Override
	public void render(float delta) {
		Gdx.gl.glViewport(0, 0, Gdx.graphics.getWidth(), Gdx.graphics.getHeight());
		Gdx.gl.glClearColor(0, 0, 0, 1);
		Gdx.gl.glClear(GL20.GL_COLOR_BUFFER_BIT | GL20.GL_DEPTH_BUFFER_BIT);

		if (!pause) {
			updatePhysics();
			room.update(delta);
		}

		modelBatch.begin(camera);
		room.render(modelBatch);
		modelBatch.end();
		drawUI();

	}

	private void drawUI() {
		if (room.isCharging()) {
			chargeRenderer.begin(ShapeType.Filled);
			chargeRenderer.rect(0, 0, Gdx.graphics.getWidth() * Math.min(Room.MAX_CHARGE_TIME, room.getChargeTimer()) / Room.MAX_CHARGE_TIME,
					Gdx.graphics.getHeight() * 0.05f);
			chargeRenderer.end();
		}
		uiBatch.begin();
		if (room.getTimer() < 10) {
			fontRed.setColor(Color.RED);
		}
		fontSmall.drawMultiLine(uiBatch, "Time:", Gdx.graphics.getWidth() * 0.5f, Gdx.graphics.getHeight() * 0.98f);
		fontRed.drawMultiLine(uiBatch, ""+ room.getTimer(), Gdx.graphics.getWidth() * 0.8f, Gdx.graphics.getHeight() * 0.98f);
		fontSmall.drawMultiLine(uiBatch, "Points: " + Locator.getStats().getScore(), Gdx.graphics.getWidth() * 0.00f,
				Gdx.graphics.getHeight() * 0.98f);
		fontSmall
				.drawMultiLine(uiBatch, "fps:" + Gdx.graphics.getFramesPerSecond(), Gdx.graphics.getWidth() * 0.0f, Gdx.graphics.getHeight() * 0.05f);
		uiBatch.end();

		crosshair.setColor(Color.RED);
		crosshair.begin(ShapeType.Filled);
		crosshair.circle(Gdx.graphics.getWidth() / 2, Gdx.graphics.getHeight() / 2, 2f);
		crosshair.end();
	}

	private void updatePhysics() {
		Locator.getWorld().stepSimulation(1.0f / 60.0f);
		Locator.getDebug().begin(camera);
		Locator.getWorld().debugDrawWorld();
		Locator.getDebug().end();
	}

	public void endGame() {
		pause();
		screenHandler.getScoreScreen().updateStats();
		screenHandler.roomToScore();
	}
	
	public void createNewRoom() {
		room=new Room(this, camera, environment, rayCallback);
		fontRed.setColor(Color.WHITE);
	}

	@Override
	public void resize(int width, int height) {
		// TODO Auto-generated method stub

	}

	@Override
	public void show() {
		pause = false;
		Gdx.input.setInputProcessor(Locator.getInputMultiplexer());
	}

	@Override
	public void hide() {
		pause = true;
		// TODO Auto-generated method stub

	}

	@Override
	public void pause() {
		pause = true;

	}

	@Override
	public void resume() {
		pause = false;
		Gdx.input.setInputProcessor(Locator.getInputMultiplexer());

	}

	@Override
	public void dispose() {
		modelBatch.dispose();

	}

}
